package com.hunk.springMvcExercise.web.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.hunk.core.Constants;
import com.hunk.utils.StringHelper;

/**
 * @author Dengyx
 *
 */
public class SessionLostFilter implements Filter {

	private List<String> excludePaths = new ArrayList<String>();
	private List<String> excludeSuffixs = new ArrayList<String>();
	// 上下文路径
	@SuppressWarnings("unused")
	private String contextPath;
	// session-lost err page relative path for root
	private String errRelativePath;
	
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO check whether the session is lost
		HttpServletRequest req = (HttpServletRequest) request;
		
		String requestPath = req.getServletPath();
		if (!requireAuthority(requestPath)) {
			chain.doFilter(request, response);
			return;
		}
		
		HttpSession map = req.getSession();
		if (null != map.getAttribute(Constants.LOGIN_USERNAME.name())) {
			Object csession = map.getAttribute(Constants.LOGIN_USERNAME.name());
			if (null == csession) {
				toErrPage(request, response);
				return;
			}
		} else {
			toErrPage(request, response);
			return;
		}
		chain.doFilter(request, response);
	}
	
	/** 判断是否需要进行资源过滤 **/
	private boolean requireAuthority(String requestPath) {
		for (String excludePath : excludePaths) {
			if (requestPath.startsWith(excludePath)) {
				return false;
			}
		}
		for (String excludeSuffix : excludeSuffixs) {
			if (requestPath.endsWith(excludeSuffix)) {
				return false;
			}
		}
		return true;
	}
	
	/** session失效的处理 **/
	private void toErrPage(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
		request.setAttribute("message", "登陆超时，请重新登陆！");
		RequestDispatcher requestDispatcher = request
				.getRequestDispatcher(errRelativePath);
		requestDispatcher.forward(request, response);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		// 默认排除掉的URL
		String loginPage = null;
		// 登录页面
		String loginPageConfig = config.getInitParameter("loginPage");
		if (StringHelper.isNotEmpty(loginPageConfig)) {
			loginPage = loginPageConfig.trim();
		}
		if (!loginPage.startsWith("/")) {
			loginPage = "/" + loginPage;
		}
		// 解析excludePaths
		excludePaths.add(loginPage);
		String excludePath = config.getInitParameter("excludePaths");
		if (StringHelper.isNotEmpty(excludePath)) {
			for (String path : excludePath.split("\\s*,\\s*")) {
				excludePaths.add(path);
			}
		}
		// 解析excludeSuffixs
		String excludeSuffix = config.getInitParameter("excludeSuffixs");
		if (StringHelper.isNotEmpty(excludeSuffix)) {
			for (String path : excludeSuffix.split(",")) {
				excludeSuffixs.add(path);
			}
		}
		errRelativePath = config.getInitParameter("errRelativePath");
		
		contextPath = config.getServletContext().getContextPath();
	}

}
